package com.zenithmind.disk.pojo.dto;

import com.zenithmind.disk.enums.ShareVisibility;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;

/**
 * 文件分享传输对象
 * 遵循单一职责原则：专注于分享数据传输
 * 遵循开闭原则：通过枚举和验证方法便于扩展
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "文件分享DTO")
public class ShareDTO {

    @Schema(description = "分享ID")
    private String id;

    @NotBlank(message = "文件ID不能为空")
    @Schema(description = "文件ID")
    private String fileId;

    @Min(value = 0, message = "过期时间不能为负数")
    @Max(value = 365, message = "过期时间不能超过365天")
    @Schema(description = "过期时间（天数），0表示永久有效")
    private Integer expireTime;

    @Schema(description = "是否公开分享，1表示公开，0表示私密")
    private Integer isPublic;

    @Size(max = 20, message = "提取密码长度不能超过20个字符")
    @Schema(description = "提取密码，私密分享时必填")
    private String password;

    // ==================== 业务方法 ====================

    /**
     * 检查是否为公开分享
     * @return true如果是公开分享
     */
    public boolean isPublicShare() {
        return isPublic != null && isPublic == 1;
    }

    /**
     * 检查是否为私密分享
     * @return true如果是私密分享
     */
    public boolean isPrivateShare() {
        return !isPublicShare();
    }

    /**
     * 检查是否永久有效
     * @return true如果永久有效
     */
    public boolean isPermanent() {
        return expireTime == null || expireTime == 0;
    }

    /**
     * 检查是否有提取密码
     * @return true如果有提取密码
     */
    public boolean hasPassword() {
        return StringUtils.isNotBlank(password);
    }

    /**
     * 获取分享可见性枚举
     * @return 分享可见性枚举
     */
    public ShareVisibility getShareVisibility() {
        return ShareVisibility.fromCode(isPublic);
    }

    /**
     * 设置分享可见性
     * @param visibility 分享可见性枚举
     */
    public void setShareVisibility(ShareVisibility visibility) {
        this.isPublic = visibility != null ? visibility.getCode() : null;
    }

    /**
     * 设置为公开分享
     */
    public void setAsPublic() {
        this.isPublic = 1;
        this.password = null; // 公开分享不需要密码
    }

    /**
     * 设置为私密分享
     * @param password 提取密码
     */
    public void setAsPrivate(String password) {
        this.isPublic = 0;
        this.password = password;
    }

    /**
     * 设置永久有效
     */
    public void setPermanent() {
        this.expireTime = 0;
    }

    /**
     * 设置过期时间（天数）
     * @param days 天数
     */
    public void setExpireInDays(int days) {
        if (days <= 0) {
            setPermanent();
        } else {
            this.expireTime = Math.min(days, 365); // 最多365天
        }
    }

    /**
     * 生成随机密码
     * @param length 密码长度
     */
    public void generateRandomPassword(int length) {
        if (length <= 0 || length > 20) {
            length = 6; // 默认6位
        }

        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder password = new StringBuilder();
        java.util.Random random = new java.util.Random();

        for (int i = 0; i < length; i++) {
            password.append(chars.charAt(random.nextInt(chars.length())));
        }

        this.password = password.toString();
    }

    /**
     * 验证DTO数据的完整性
     * @return true如果数据有效
     */
    public boolean isValid() {
        if (StringUtils.isBlank(fileId)) {
            return false;
        }

        // 私密分享必须有密码
        if (isPrivateShare() && !hasPassword()) {
            return false;
        }

        // 过期时间验证
        if (expireTime != null && (expireTime < 0 || expireTime > 365)) {
            return false;
        }

        // 密码长度验证
        if (hasPassword() && password.length() > 20) {
            return false;
        }

        return true;
    }

    /**
     * 获取分享类型描述
     * @return 分享类型描述
     */
    public String getShareTypeDescription() {
        if (isPublicShare()) {
            return "公开分享";
        } else {
            return "私密分享";
        }
    }

    /**
     * 获取过期时间描述
     * @return 过期时间描述
     */
    public String getExpireTimeDescription() {
        if (isPermanent()) {
            return "永久有效";
        } else {
            return expireTime + "天后过期";
        }
    }

    /**
     * 清理敏感信息（用于日志记录）
     * @return 清理后的DTO副本
     */
    public ShareDTO sanitizeForLogging() {
        ShareDTO sanitized = new ShareDTO();
        sanitized.setId(this.id);
        sanitized.setFileId(this.fileId);
        sanitized.setExpireTime(this.expireTime);
        sanitized.setIsPublic(this.isPublic);
        // 不复制密码
        return sanitized;
    }
}